import ir.DataNode;
import ir.LocatorServicePair;
import ir.SoapRootNode;
import ir.StubNode;
import ir.TranslatorGenerator;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;


public class SoapGwtCompiler {


  /**
   * @param args
   * @throws ClassNotFoundException 
   */
  public static void main(String[] args) throws ClassNotFoundException {
    
    System.out.println("Preparing to parse stubs ...");
    
    String packageRoot = "netgravity.webservices.services";
    
    String[] services = {
    "AdService",
    "AdSizeService",
    "AdvertiserService",
    "AffiliateService",
    "AgencyService",
    "ContactService",
    "CreativeService",
    "CurrencyTypeService",
    "EventTypeService",
    "ExchangeRateService",
    "FlightService",
    "FrequencyCapGroupService",
    "IndustryService",
    "MarketSegmentGroupService",
    "MarketSegmentService",
    "OrderService",
    "PaymentTypeService",
    "ProductService",
    "RateCardService",
    "SOAPMonitorService",
    "SegmentationVariableService",
    "SiteService",
    "StyleService",
    "UserService" };

    
    //  bundle locators with stubs
    List<LocatorServicePair> locatorServicePairs = new ArrayList<LocatorServicePair>();
    
    // fetch all Locator and Service class' class objects
    for (String servicename : services) {
      String packageName = packageRoot + "." + servicename;
      Class<Object> serviceLocatorClass = 
        (Class<Object>) Class.forName(packageName + "." + servicename + "ServiceLocator");
      Class<Object> stubClass = 
        (Class<Object>) Class.forName(packageName + "." + servicename + "SoapBindingStub");
      
      locatorServicePairs.add(new LocatorServicePair(stubClass, 
          serviceLocatorClass, servicename));
    }
    
    StubTreeWalker walker = new StubTreeWalker(locatorServicePairs);
    
    SoapRootNode rootNode = walker.getRootNode();
    String rootDir = "/home/tchau/workspace/SoapGwtIntegrator/output/soapgwt/";
    // pregenerate the directories if they don't exist
    (new File(rootDir + "client/")).mkdirs();
    (new File(rootDir + "client/services/")).mkdirs();
    (new File(rootDir + "client/types/")).mkdirs();
    (new File(rootDir + "server/translator/")).mkdirs();
    (new File(rootDir + "server/")).mkdirs();
    
    Set<DataNode> dataNodes = rootNode.getDataNodes();
    for (DataNode d : dataNodes) {
      // output datanode gen() to com/google/gwtsoap/types
      outputFile(d.gen(), d.getGeneratedClassName() + ".java", rootDir + "client/types/");
      
      System.out.println("<inherits name='" + d.getPackage() + "." + d.getGeneratedClassName() + "' />");
    }

    /*
     * TODO: build Service interfaces, Service async interfaces, and ServiceImpls
     */
    Set<StubNode> stubNodes = rootNode.getStubNodes();
    for (StubNode d : stubNodes) {
      outputFile(d.genServiceInterface(), d.getServiceName() + ".java", rootDir + "client/services/");
      outputFile(d.genServiceAsyncInterface(), d.getServiceAsyncName() + ".java", rootDir + "client/services/");
      outputFile(d.gen(), d.getClassname() + ".java", rootDir + "server/");
      
    }
    
    // Generate Translator object
    TranslatorGenerator translatorGenerator =
      new TranslatorGenerator( rootNode.getDataNodes() );
    String translatorClass = translatorGenerator.gen();
    
    
    outputFile(translatorClass, "Translator.java", rootDir + "server/translator/");
    
    
    System.out.println("Done. " + ( dataNodes.size() + stubNodes.size() ) +
        " types found.");
    
  }

  private static void outputFile(String classFile, String fileName, String resultDir) {
    
    PrintWriter writer;
    File outFile;
    outFile = new File(resultDir, fileName);
    try {
      
      writer = new PrintWriter(new FileWriter(outFile), true);
      writer.write(classFile);
      
      writer.close();
    } catch (IOException e) {
      e.printStackTrace();
    }

  }
}
